package net.davidlauzon.assemblandroid.views;

import net.davidlauzon.assemblandroid.R;
import net.davidlauzon.assemblandroid.TimeTrackerApplication;
import net.davidlauzon.assemblandroid.TimeTrackerModel.ACTIVITY;
import net.davidlauzon.assemblandroid.models.Task;
import net.davidlauzon.assemblandroid.models.Ticket;
import net.davidlauzon.assemblandroid.models.Task.State;
import net.davidlauzon.utils.IObserver;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class TimeEntryActivity extends Activity implements IObserver {
	static private final String TAG = "AssemblaTT";

	// GRASP Controller
	private TimeTrackerApplication app;
	
	private Button btnPauseResume;
	private TextView txtElapsedTime;
	private EditText editLogMessage;
	
	private ShowElapsedTimeTask showTimerTask;

	private ProgressDialog loadingDialog;
	
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "TimeEntryActivity::onCreate()");
        
        // Data
        app = TimeTrackerApplication.getInstance();
        
        Task task     = app.curTask();
        Ticket ticket = app.curTicket();
        
        // View
        setContentView(R.layout.time_entry);
        
        LinearLayout layout = (LinearLayout) findViewById(R.id.timeEntryLayout);
        
        TextView txtView = (TextView) layout.findViewById(R.id.txtSpaceName);
        txtView.setText( "Project: " + app.curProject().name() );
        txtView = (TextView) layout.findViewById(R.id.txtTicketName);
        txtView.setText( "Ticket:  " + ticket.longFormattedName() );
        txtView = (TextView) layout.findViewById(R.id.txtTicketDescription);
        txtView.setText( "Description: \n" + ticket.description() );
        txtView = (TextView) layout.findViewById(R.id.txtStartedAt);
        txtView.setText( "Started at: " + task.beginAt().toString() );
        
        btnPauseResume = (Button) layout.findViewById(R.id.btnPauseResume);
        btnPauseResume.setText("Pause");
        
        txtElapsedTime = (TextView) layout.findViewById(R.id.txtElapsedTime);
        editLogMessage = (EditText) layout.findViewById(R.id.editLogMessage);
        editLogMessage.setText(ticket.lastLogMessage());
        
        // Start the task:
        showTimerTask = new ShowElapsedTimeTask();
        showTimerTask.execute(task);
    }
    
    public void onPauseResumeClicked(View v) {
    	if (app.togglePauseTimeEntry() == State.STARTED)
    		btnPauseResume.setText( "Pause" );
    	else
    		btnPauseResume.setText( "Resume" );
    }
    
    public void onStopClicked(View v) {
    	commitTimeEntry(false);
    }
    
    public void onMarkToTestClicked(View v) {
    	commitTimeEntry(true);
    }
    
    /**
     * Since the back button's behavior is overwritten, we need a way out.
     * @param v
     */
    public void onCancelClicked(View v) {
    	//Log.i(TAG, "onCancelClicked");
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setMessage("Are you sure you cancel this time entry ?");
    	builder.setCancelable(false);
    	builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
    		public void onClick(DialogInterface dialog, int id) {
    			TimeEntryActivity.this.finish();
    		}
    	});
    	builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
    		public void onClick(DialogInterface dialog, int id) {
    			dialog.cancel();
    		}
    	});
    	AlertDialog alert = builder.create();
    	alert.show();
    }
    
    
    private void commitTimeEntry(boolean markToTest) {
    	// The controller will automatically update the data
    	app.stopTimeEntry();
    	app.saveTimeEntryLater( editLogMessage.getText().toString(), markToTest, this );
    	
    	loadingDialog = ProgressDialog.show(this, "", "Saving time entry. Please wait...", true);
    }

	
    public void onUpdate() {
    	//Log.i(TAG, "Timeentry onUpdate!!!");
    	
        Toast.makeText( getApplicationContext(), 
        			"Time Entry Saved! " + app.curTask().elapsedTime() + " hours logged.", 
        			Toast.LENGTH_LONG).show();
        
    	// Going back to previous activity
    	// 
    	// http://stackoverflow.com/questions/4038479/android-go-back-to-previous-activity
    	// * interesting article on changing default press behaviour
    	// http://android-developers.blogspot.com/2009/12/back-and-other-hard-keys-three-stories.html
    	// http://developer.android.com/reference/android/content/Intent.html
    	finish();
	}

	public void onUpdateFailed(Exception exception) {
		Log.i(TAG, "onUpdateFailed()");
		hideLoadingDialog();
		btnPauseResume.setText( "Resume" );
	}
	
	private void hideLoadingDialog() {
		if (loadingDialog != null) {
        	loadingDialog.cancel();
        	loadingDialog = null;
        }
	}
    
    
    /**
     * Override the default back button behaviour to force saving of time entry.
     * 
     * The Activity won't finish until the task is commited.
     */
    @Override
    public void onBackPressed() {
    	commitTimeEntry(false); 
    }
    
    @Override
    public void onResume() {
        super.onResume();
        Log.i(TAG, "TimeEntryActivity::onResume()");
        app.onActivityChanged(ACTIVITY.TIME_ENTRY);
    }
    
    @Override
    public void onDestroy() {
    	super.onDestroy();
        Log.i(TAG, "TimeEntryActivity::onDestroy()");
    	showTimerTask.cancel(true);
    }
	
    
    private class ShowElapsedTimeTask extends AsyncTask<Task, Task, Void>
    {
    	private Task task;

		@Override
		protected Void doInBackground(Task... params) {
			Log.i(TAG, "ShowElapsedTimeTask::doInBackground");
			if (params.length > 0) { 
				task = params[0];
				
				try {
					do {
						Thread.sleep(1 * 1000);
						publishProgress(task);
					} while ( !isCancelled() );
					
					//Log.i(TAG, "Task has been gracefully cancelled!");
				
				} catch (InterruptedException e) {
					//e.printStackTrace();
					Log.i(TAG, "ShowElapsedTimeTask has been interrupted!");
					cancel(true);
				}
				
				return null;
			} else {
				Log.e(TAG, "Missing Task argument!");
				return null;
			}
		}
    	
		protected void onProgressUpdate(Task... params) {
			//Log.i(TAG, "onProgressUpdate  ");
			if (params.length == 0)  return ;
			task = params[0];
			
			txtElapsedTime.setText( "Elapsed Time: " + task.elapsedTime() );
		}
    	
		protected void onCancelled() {
			Log.i(TAG, "ShowElapsedTime::onCancelled");
		}
    }

}
